package org.mbcorp.sar.controller;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletResponse;

import org.mbcorp.sar.model.Area;
import org.mbcorp.sar.model.CalendarioJsonDTO;
import org.mbcorp.sar.model.Fase;
import org.mbcorp.sar.model.Horario;
import org.mbcorp.sar.model.ListasEmail;
import org.mbcorp.sar.model.Operador;
import org.mbcorp.sar.model.Solicitud;
import org.mbcorp.sar.model.TipoRequerimiento;
import org.mbcorp.sar.service.AlertaService;
import org.mbcorp.sar.service.ArchivoService;
import org.mbcorp.sar.service.AreaService;
import org.mbcorp.sar.service.FaseService;
import org.mbcorp.sar.service.HorarioService;
import org.mbcorp.sar.service.OperadorService;
import org.mbcorp.sar.service.SolicitudService;
import org.mbcorp.sar.service.TipoRequerimientoService;
import org.mbcorp.sar.validator.HorarioValidator;
import org.mbcorp.sar.validator.SolicitudValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.MessageSource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.Gson;

@PreAuthorize(value = "hasRole('ROLE_COORDINADOR')")
@Controller
public class RealizarProgramacionController {

	@Autowired
    private MessageSource messageSource;

	@Autowired
	private SolicitudService solicitudService;
	
	@Autowired
	private OperadorService operadorService;
	
	@Autowired
	private AreaService areaService;
	
	@Autowired
	private ArchivoService archivoService;
	
	@Autowired
	private FaseService faseService;
	
	@Autowired
	private HorarioService horarioService;
	
	@Autowired
	private TipoRequerimientoService tipoRequerimientoService;
	
	@Autowired
	private SolicitudValidator solicitudValidator;
	
	@Autowired
	private HorarioValidator horarioValidator;
	
	@Autowired
	private AlertaService alertaService;
	
	@InitBinder
	public void initDateBinder(final WebDataBinder dataBinder, final Locale locale) {
	    final String dateformat = this.messageSource.getMessage("date.format", null, locale);
	    final SimpleDateFormat sdf = new SimpleDateFormat(dateformat);
	    sdf.setLenient(false);
	    dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, false));
	}

	@RequestMapping(value = "/realizarProgramacion", method = RequestMethod.GET)
	public String buscarSolicitudes(Solicitud solicitud, Model model) {
			List<Solicitud> listaPrioritarios = solicitudService.buscarPrioritarios();
			if(!listaPrioritarios.isEmpty()){
				model.addAttribute("tienePrioritarios", true);
			}
			model.addAttribute("listaSolicitudes", listaPrioritarios);
		return "consultarProgramacion";
	}
	
	@RequestMapping(value = "/consultarProgramacion", method = RequestMethod.POST)
	public String mostrarResultados(Model model, Solicitud solicitud, BindingResult result) {
		if(!solicitudValidator.validarRangoFechas(solicitud, result)){
			model.addAttribute("flagError", true);
			return "consultarProgramacion";
		}
		List<Solicitud> listaSolicitudes = solicitudService.buscarPrioritarios();
		if(!listaSolicitudes.isEmpty()){
			model.addAttribute("tienePrioritarios", true);
		}
		listaSolicitudes.addAll(solicitudService.buscarPorFiltrosClienteFechaEstimadoNoPrioritarios(solicitud));
		model.addAttribute("listaSolicitudes", listaSolicitudes);
		return "consultarProgramacion";
	}

	@RequestMapping(value = "/programarSolicitud/{id}", method = RequestMethod.GET)
	public String mostrarDetalle(@PathVariable Integer id, Model model) {
		Solicitud s = solicitudService.armarSolicitud(id);		
		solicitudService.armarColisionesHorarios(s);
		model.addAttribute("solicitud", s);		
		return "programarSolicitud";
	   }
	
	@ModelAttribute("allAreas")
	public List<Area> llenarAreas() {
	    return areaService.buscarTodos();
	}
	
	@ModelAttribute("allTipoRequerimientos")
	public List<TipoRequerimiento> llenarTipoRequerimientos() {
	    return tipoRequerimientoService.buscarTodos();
	}
	
	@RequestMapping(value = "/getFechas/{id}", method = RequestMethod.GET)
    public @ResponseBody String getFechas(HttpServletResponse response, @PathVariable Integer id) {
		List<Horario> horarios = horarioService.buscarPorOperador(id);
        System.out.println("se llamo calendar"+id);
        List<CalendarioJsonDTO> listaHorario= horarioService.armarCalendario(horarios);		
        // Convert to JSON string.
        String json = new Gson().toJson(listaHorario);

        // Write JSON string.
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        System.out.println(json);
        return json;
    }
	
	@RequestMapping(value = "/getIgnorados/{idOperador}/{idSolicitud}", method = RequestMethod.GET)
    public @ResponseBody String getIgnorados(HttpServletResponse response, @PathVariable Integer idOperador, @PathVariable Integer idSolicitud) {
		List<Horario> horarios = horarioService.buscarIgnorados(idOperador,idSolicitud);
		System.out.println("Ignorados: "+ horarios.size());
        List<CalendarioJsonDTO> listaHorario= horarioService.armarCalendario(horarios);		
        // Convert to JSON string.
        String json = new Gson().toJson(listaHorario);

        // Write JSON string.
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        System.out.println(json);
        return json;
    }
	
	@RequestMapping(value = "/getRestringidos", method = RequestMethod.GET)
    public @ResponseBody String getRestringidos(HttpServletResponse response) {
		List<Horario> restringidos = horarioService.buscarRestringidos();
        List<CalendarioJsonDTO> listaEspeciales= horarioService.armarRestringidos(restringidos);		
        // Convert to JSON string.
        String json = new Gson().toJson(listaEspeciales);

        // Write JSON string.
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        System.out.println(json);
        return json;
    }
	
	
	@RequestMapping(value = "/getPrevi/{fecha}/{hora}/{total}/{idOperador}", method = RequestMethod.GET)
    public @ResponseBody String getPrevisualizacion(HttpServletResponse response, @PathVariable String fecha, @PathVariable int hora, @PathVariable int total, @PathVariable int idOperador) {		
        
        List<CalendarioJsonDTO> listaHorario= horarioService.armarPrevi(fecha, hora, total, idOperador);        
        
        // Convert to JSON string.
        String json = new Gson().toJson(listaHorario);

        // Write JSON string.
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        System.out.println(json);
        return json;
    }
	
	@RequestMapping(value = "/programarOperador/{idFase}/{idOperador}", method = RequestMethod.GET)
	public String programarOperador(@PathVariable Integer idFase, @PathVariable Integer idOperador, Model model, Horario horario) {		
		Operador o = operadorService.buscarPorId(idOperador);
		model.addAttribute("operador", o);
		Fase f = faseService.buscarPorId(idFase);
		model.addAttribute("fase", f);
		model.addAttribute("solicitud", f.getSolicitud());
		return "programarOperador";
   }
	
	@RequestMapping(value = "/programarOperador", method = RequestMethod.POST)
	public String programarHorario(Model model, @RequestParam("idOperador") Integer idOperador, @RequestParam("idFase") Integer idFase, @ModelAttribute("horario") Horario horario, BindingResult result) {	
		if (result.hasErrors()){
			model.addAttribute("horario", horario);
			return programarOperador(idFase, idOperador, model, horario);
		}
		Operador o = operadorService.buscarPorId(idOperador);
		Fase f = faseService.buscarPorId(idFase);
		Horario h = horarioService.armarHorario(horario.getFechaInicio(), horario.getHoraInicio(), horario.getHorasTotal(), o, f);
		horarioValidator.validarCruce(h, o, result);
		if (result.hasErrors()){
			model.addAttribute("horario", horario);
			return programarOperador(idFase, idOperador, model, horario);
		}
		horarioService.grabar(h);
		Solicitud s = solicitudService.armarSolicitud(f.getSolicitud().getId());
		model.addAttribute("solicitud", s);
		return "programarSolicitud";
   }
	
	@RequestMapping(value = "/eliminarHorario/{horarioId}", method = RequestMethod.DELETE)
	public String eliminarHorario(@PathVariable Integer horarioId){
		Integer solicitudId = horarioService.buscarPorId(horarioId).getFase().getSolicitud().getId();
			horarioService.eliminar(horarioId);
		return "redirect:../programarSolicitud/" + solicitudId;
	}
	
	@RequestMapping(value = "/revisarProgramacion", method = RequestMethod.GET)
	public String revisarProgramacion(Model model, @RequestParam("idSolicitud") Integer idSolicitud){
		Solicitud s = solicitudService.armarSolicitud(idSolicitud);
		if (!solicitudValidator.tieneProgramaciones(s)){
			model.addAttribute("flagErrorProgramacion", true);
			return mostrarDetalle(idSolicitud, model);
		}
		if (solicitudValidator.tieneCruces(s)){
			model.addAttribute("flagErrorCruces", true);
			return mostrarDetalle(idSolicitud, model);
		}
		
		model.addAttribute("solicitud", s);
		return "revisarProgramacion";
	}
	
	@RequestMapping(value = "/getCalendarioSolicitud/{idSolicitud}", method = RequestMethod.GET)
    public @ResponseBody String getCalendarioSolicitud(HttpServletResponse response, @PathVariable Integer idSolicitud) {
		List<CalendarioJsonDTO> calendario = horarioService.armarCalendarioSolicitud(solicitudService.buscarPorId(idSolicitud));	
        // Convert to JSON string.
        String json = new Gson().toJson(calendario);

        // Write JSON string.
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        System.out.println(json);
        return json;
    }
	
	@RequestMapping(value = "/enviarProgramacion", method = RequestMethod.POST)
	public String enviarProgramacion(Model model, @RequestParam("idSolicitud") Integer idSolicitud) {
		Solicitud s = solicitudService.armarSolicitud(idSolicitud);
		if(s.getFechaAcordadaEntrega() == null){
			solicitudService.enviarProgramacion(s);
			alertaService.mandarAlerta(s, ListasEmail.CLIENTE);
			alertaService.mandarAlertaOperadores(s);
		} else {
			if(s.isFlagFueraPlazoAprobacion() && s.getFechaAcordadaEntrega().equals(s.getFechaEstimadaEntrega())){
				System.out.println("Aprobado directamente");
				solicitudService.aprobarProgramacion(s);
			} else {
				System.out.println("Reprogramado");
				solicitudService.reenviarProgramacion(s);
				alertaService.mandarAlerta(s, ListasEmail.CLIENTE);
			}
		}
			
//		model.addAttribute("modoConsulta", true);
//		model.addAttribute("confirmaRegistro", true);			
		
		return "intro";
	}	
	
}
